package com.foreveross.utils.crypt;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
 * description: 记录每个模块的加密文件列表
 *
 * @author: wzq
 * @date: 2014/6/3
 */
class CryptList {
    // 是否所有文件加密
    private final static boolean isAllFileEncrypt = false;

    /**
     * 从文件路径,得到模块的Id 和 文件相对路径
     * /mnd/sdcard/com.foreveross.chameleon/www/com.csair.weather/module.js
     * => id= com.csair.weather, 相对路径 module.js
     */
    private static class FilePathInfo {
        private static final String ROOT_ID = "this is the root id";
        /**
         * 对应模块ID
         */
        final String id;
        /**
         * 模块相对根目录的路径
         */
        final String relativePath;

        @Override
        public String toString() {
            return "FilePathInfo{" +
                    "id='" + id + '\'' +
                    ", relativePath='" + relativePath + '\'' +
                    '}';
        }
        public FilePathInfo(String fullPath) {
            int indexRoot = WebFileProvider.MODULE_ROOT_IN_SD.length();
            String idAndRelativePaht = fullPath.substring(indexRoot + 1);
            int idEndIndex = idAndRelativePaht.indexOf("/");
            if(idEndIndex == -1) {
                id = ROOT_ID;
                relativePath = idAndRelativePaht;
            } else {
                id = idAndRelativePaht.substring(0, idEndIndex);
                relativePath = idAndRelativePaht.substring(idEndIndex + 1);
            }
        }

        /**
         * 获取该id对应模块的sandbox.json文件
         */
        public String getFileSandbox() {
            StringBuilder sb = new StringBuilder();
            sb.append(WebFileProvider.MODULE_ROOT_IN_SD);
            if(id != null) {
                if(ROOT_ID.equals(id)) {
                    sb.append("/sandbox.json");
                } else {
                    sb.append("/" + id + "/sandbox.json");
                }

            }
            return sb.toString();
        }

        /**
         * 获取相对于根目录的 相对路径
         *
         * @param fullPath
         *
         * @return
         */
        public String getRelativePath(String fullPath) {
            return relativePath;
        }

    }

    /**
     * 保存加密列表
     */
    public static Map<String, List<String>> cryptMap;

    /**
     * TODO:根据文件url解析出对应模块，由模块配置决定是否需要对此文件做解密处理
     * 逻辑如下:如果在该文件的文件夹下，有sandbox.json则，读取json文件判断是否加密
     * 如果没有则认为加密
     */
    public static boolean isCrypt(String filePath) {
        // 临时策略
        if(true){
            return true;
        }
        // 临时策略


        if(isAllFileEncrypt) {
            return true;
        }

        if(!filePath.startsWith(WebFileProvider.MODULE_ROOT_IN_SD)) {
            throw new RuntimeException(" filePath必须是sd卡中文件全路径, filePath:" + filePath);
        }

        FilePathInfo filePathInfo = new FilePathInfo(filePath);

        if(cryptMap == null) {
            cryptMap = new HashMap<String, List<String>>();
        }
        if(filePathInfo.id != null) {
            initModuleCryptList(filePathInfo);
        }
        List<String> moduleCryptList = cryptMap.get(filePathInfo.id);
        if(moduleCryptList != null) {
            if(moduleCryptList.contains(filePathInfo.relativePath)) {
                return true;
            }
        }
        return false;
    }


    /**
     * 记录下一个模块的加密信息:读取模块的 sandbox.json,然后放在list中
     */
    private static void initModuleCryptList(FilePathInfo filePathInfo) {
        // add crypt info of this module
        if(cryptMap.get(filePathInfo.id) == null) {
            List<String> cryptFileList = new ArrayList<String>();
            String sandboxFile = filePathInfo.getFileSandbox();
            File file = new File(sandboxFile);
            if(file.exists()) {
                try {
                    InputStream in = new FileInputStream(file);
                    String str = CryptUtils.stream2String(in, "utf8");
                    String[] split = str.split(",");
                    for(String s : split) {
                        cryptFileList.add(s);
                    }
                } catch(IOException e) {
                    e.printStackTrace();
                }
            }
            cryptMap.put(filePathInfo.id, cryptFileList);
        }
    }
}
